package winOrDie.Net.P2P;

import java.util.Vector;

import rice.p2p.commonapi.Node;
import winOrDie.Net.WoD_Net_Protocol_ASCII;
import winOrDie.Net.WoD_Net_Protocol_Manager;
import winOrDie.Net.Client.WoD_Client_ControlChannel_Event;
import winOrDie.Net.Server.WoD_Server_ControlChannel_Event;

public class WoD_P2P_Control_Channel implements WoD_Scribe_Channel_Listener 
{
	
	private WoD_Scribe_Channel woDScribeChannel = null;
	
	private WoD_Net_Protocol_Manager woDNetProtocolManager = null;
	
	private Vector<WoD_P2P_Control_Channel_Listener> listeners = null;
	
	public synchronized void add_WoD_P2P_Control_Channel_Listener (WoD_P2P_Control_Channel_Listener listener)
	{
		listeners.add(listener);
	}
	
	public synchronized void remove_WoD_P2P_Control_Channel_Listener (WoD_P2P_Control_Channel_Listener listener)
	{
		listeners.remove(listener);
	}
	
	protected void fire_WoD_P2P_Control_Channel_Event(WoD_P2P_Control_Channel_Event event)
	{
		for (WoD_P2P_Control_Channel_Listener listener : listeners) {
			listener.on_WoD_P2P_Control_Channel_Change(event);
		}
	}
	
	public WoD_Scribe_Channel getWoDScribeChannel() {
		return woDScribeChannel;
	}

	public WoD_P2P_Control_Channel(Node node) {
		listeners = new Vector<WoD_P2P_Control_Channel_Listener>();
		woDNetProtocolManager = new WoD_Net_Protocol_Manager();
		
		woDScribeChannel = new WoD_Scribe_Channel(node);
		woDScribeChannel.add_WoD_Scribe_Channel_Listener(this);
	}
	
	public void start_WoD_P2P_Control_Channel()
	{
		woDScribeChannel.start_Wod_Scribe_Channel();
		woDScribeChannel.send_New_Node();
		woDScribeChannel.subscribe();
		//woDScribeChannel.check_Root();
		
	}
	
	/**
	 * This private method parses application level messages
	 * @param woDScribeContent
	 */
	private void parse_Control_Message(WoD_ScribeContent woDScribeContent)
	{
		//String message = woDScribeContent.getMessage().toString();
		//final String header = message.split(" ")[0];
		String header =  null;
		try {
			header = woDNetProtocolManager.parse_Header(woDScribeContent.getMessage());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		
		WoD_P2P_Control_Channel_Event event = null;
		
		if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Chat))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CHAT);
			//event.setData(message);
			try {
				event.setData(woDNetProtocolManager.parse_Chat_Message(woDScribeContent.getMessage())	
					);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return;
			}
			
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Notify_Id_Game))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.GAME_ID);
			
			try {
				event.setData(woDNetProtocolManager.parse_Game_Id_Message(woDScribeContent.getMessage())	
					);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return;
			}			
			
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameMenu.Join_Game))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.SERVER_JOIN_GAME);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameMenu.Join_Game_KO))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_JOIN_GAME_KO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameMenu.Join_Game_OK))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_JOIN_GAME_OK);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.New_User_Info))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_USER_INFO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Users_Info))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_GAME_INFO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Leave_Game))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_LEAVE_GAME);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Side))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.SERVER_SELECT_SIDE);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Side_Info))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_SELECT_SIDE_INFO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Side_OK))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_SELECT_SIDE_OK);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Side_KO))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_SELECT_SIDE_KO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Ready_to_Go))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.SERVER_READY_TO_GO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Ready_to_Go_OK))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_READY_TO_GO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Ready_to_Go_KO))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.SERVER_READY_TO_GO_KO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Change_Map))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CHANGE_MAP);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Not_Ready_to_Go))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_READY_TO_GO_KO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Force_Start))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.SERVER_FORCE_START);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		else if (header.equals(WoD_Net_Protocol_ASCII.RealTime_Control.Count_Down))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.SERVER_COUNT_DOWN);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		} 
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Rol))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.SERVER_SELECT_ROL);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		} 
		else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Rol_Info))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_SELECT_ROL_INFO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Rol_OK))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_SELECT_ROL_OK);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}else if (header.equals(WoD_Net_Protocol_ASCII.GameRoom.Select_Rol_KO))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.CLIENT_SELECT_ROL_KO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		
		/**
		 **********************************************************************************
		 * Real time Control
		 **********************************************************************************
		 */
		else if (header.equals(WoD_Net_Protocol_ASCII.RealTime_Control.Synchronism_Info))
		{
			event = new WoD_P2P_Control_Channel_Event(this);
			event.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.RT_CLIENT_SYNC_INFO);
			event.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(event);
			return;
		}
		
	}
	
	
	
	
	
	
	@Override
	public void on_WoD_Scribe_Channel_Change(WoD_Scribe_Channel_Event event) 
	{
		
		// Get WoD_ScribeContent
		WoD_ScribeContent woDScribeContent = (WoD_ScribeContent) event.getData();

		WoD_P2P_Control_Channel_Event woDP2PControlChannelEvent = null;
		
		switch (event.getEvent_Type()) 
		{
		
		
		/**
		 * This node is the Scribe topic Root.
		 * Shall send game information to all peers.
		 */
		case WoD_Scribe_Channel_Event.I_AM_ROOT:
			woDP2PControlChannelEvent = new WoD_P2P_Control_Channel_Event(this);
			woDP2PControlChannelEvent.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.P2P_I_AM_ROOT);
			fire_WoD_P2P_Control_Channel_Event(woDP2PControlChannelEvent);
			break;

		/**
		 * Game Root changed
		 */
		case WoD_Scribe_Channel_Event.NEW_ROOT:
			woDP2PControlChannelEvent = new WoD_P2P_Control_Channel_Event(this);
			woDP2PControlChannelEvent.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.P2P_NEW_ROOT);
			woDP2PControlChannelEvent.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(woDP2PControlChannelEvent);
			break;

		/**
		 * New node connected to Scribe topic
		 */
		case WoD_Scribe_Channel_Event.NEW_NODE:
			woDP2PControlChannelEvent = new WoD_P2P_Control_Channel_Event(this);
			woDP2PControlChannelEvent.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.P2P_NEW_NODE);
			woDP2PControlChannelEvent.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(woDP2PControlChannelEvent);
			break;


		/**
		 * Node disconnected from Scribe topic
		 */
		case WoD_Scribe_Channel_Event.NODE_DOWN:
			woDP2PControlChannelEvent = new WoD_P2P_Control_Channel_Event(this);
			woDP2PControlChannelEvent.setEvent_Type(WoD_P2P_Control_Channel_Event.Event_Types.P2P_NODE_DOWN);
			woDP2PControlChannelEvent.setData(woDScribeContent);
			fire_WoD_P2P_Control_Channel_Event(woDP2PControlChannelEvent);
			break;


		/**
		 * If it's application message parse it.
		 */
		case WoD_Scribe_Channel_Event.MESSAGE_RECEIVED:
			parse_Control_Message(woDScribeContent);
			break;


		default:
			break;
		}
		
	}

}
